package com.lmx.persistence.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lmx.common.constants.CommonConstants;
import com.lmx.common.constants.ICommonConstants;
import com.lmx.common.context.ActionContextHolder;
import com.lmx.repoDomain.tmodel.AppraiseItem;
import com.lmx.repoDomain.tmodel.Bed;
import com.lmx.repoDomain.tmodel.CommonInitConstant;
import com.lmx.repoDomain.tmodel.Conf;
import com.lmx.repoDomain.tmodel.Customer;
import com.lmx.repoDomain.tmodel.Dicttype;
import com.lmx.repoDomain.tmodel.DicttypeTenant;
import com.lmx.repoDomain.tmodel.Employee;
import com.lmx.repoDomain.tmodel.NursingLevel;
import com.lmx.repoDomain.tmodel.NursingLevelServiceItem;
import com.lmx.repoDomain.tmodel.NursingProject;
import com.lmx.repoDomain.tmodel.Privilege;
import com.lmx.repoDomain.tmodel.ServiceFinishLevel;
import com.lmx.repoDomain.tmodel.SysConfig;
import com.lmx.repoDomain.tmodel.Tenant;
import com.lmx.repoDomain.tmodel.TenantPrivilege;
import com.lmx.repoDomain.tmodel.TypegroupTenant;
import com.lmx.repoDomain.tmodel.business.User;

/**
 * 手机端初始化加载时的数据集合Service实现
 *
 * @author ytche
 * @date 2017年7月14日
 *
 */
@Service(value = "commonInitConstantsService")
public class CommonInitConstantServiceImpl implements CommonInitConstantService {
	@Autowired
	private GenericService<Dicttype> dslService;
	@Autowired
	private DicttypeService dicttypeService;
	@Autowired
	private DicttypeTenantService dicttypeTenantService;
	@Autowired
	private ServiceFinishLevelService levelService;
	@Autowired
	private BedService bedService;
	@Autowired
	private CustomerService<Customer> customerService;
	@Autowired
	private TenantPrivilegeService tenantPrivilegeService;
	@Autowired
	private PrivilegeService<Privilege> privilegeService;
	@Autowired
	private ConfService confService;
	@Autowired
	private NursingLevelService nursingLevelService;
	@Autowired
	private NursingLevelServiceItemService nursingLevelItemService;
	@Autowired
	private StaffCustomerService staffCustomerService;
	@Autowired
	private CustomerLeaveService customerLeaveService;
	@Autowired
	private EmployeeService<Employee> employeeService;
	@Autowired
	private AppraiseItemService appraiseItemService;
	@Autowired
	private NursingProjectService nursingProjectSrv;

	@Override
	@Transactional(readOnly = true)
	public List<CommonInitConstant> findAllOfMobile(Map<String, String> filter, Long tenantId) {
		List<CommonInitConstant> mobileConstants = Lists.newArrayList();
		CommonInitConstant mobileConstant = new CommonInitConstant();
		mobileConstant.setId(1L);
		initDicttype(mobileConstant);
		initSysConfig(mobileConstant);
		initDicttypeTenant(tenantId, mobileConstant);
		initFinishLevel(mobileConstant, tenantId, false);
		initBeds(tenantId, mobileConstant);
		initEmployees(tenantId, mobileConstant);
		initCustomers(tenantId, mobileConstant);
		this.initConf(mobileConstant);
		mobileConstants.add(mobileConstant);
		return mobileConstants;
	}

	@Override
	@Transactional(readOnly = true)
	public Iterable<CommonInitConstant> findAllOfPC(Map<String, String> filter, Long tenantId) {
		List<CommonInitConstant> PContants = Lists.newArrayList();
		CommonInitConstant initConstant = new CommonInitConstant();
		initConstant.setId(1L);
		this.initDicttype(initConstant);
		this.initSysConfig(initConstant);
		this.initTenantPrivileges(tenantId, initConstant);
		if (tenantId.equals(CommonConstants.ADMIN_TENANT_ID)) {
			this.initOperationPrivileges(tenantId, initConstant);
		}
		this.initDicttypeTenant(tenantId, initConstant);
		this.initConf(initConstant);
		this.initNursingLevel(tenantId, initConstant);
		this.initNursingLeveItem(tenantId, initConstant);
		initEmployees(tenantId, initConstant);
		if (this.checkJujia()) {
			this.initStaffCustomer(tenantId, initConstant);
		}
		this.initBeds(tenantId, initConstant);
		this.initCustomers(tenantId, initConstant);
		PContants.add(initConstant);
		return PContants;
	}

	@Override
	@Transactional(readOnly = true)
	public Iterable<CommonInitConstant> findAllOfOfficalAccount(Map<String, String> filter,
			Long tenantId) {
		List<CommonInitConstant> officalAccountContant = Lists.newArrayList();
		CommonInitConstant initConstant = new CommonInitConstant();
		initConstant.setId(1L);
		this.initDicttype(initConstant);
		this.initSysConfig(initConstant);
		this.initTenantPrivileges(tenantId, initConstant);
		this.initDicttypeTenant(tenantId, initConstant);
		this.initConf(initConstant);
		this.initStaffCustomer(tenantId, initConstant);
		this.initFinishLevel(initConstant, tenantId, false);
		this.initBeds(tenantId, initConstant);
		this.initAppraiseItem(tenantId, initConstant);
		officalAccountContant.add(initConstant);
		return officalAccountContant;
	}

	private void initAppraiseItem(Long tenantId, CommonInitConstant initConstant) {
		Map<String, Object> param = Maps.newHashMap();
		param.put("delStatus", CommonConstants.DEL_STATUS_NO_0);
		param.put("tenant.id", tenantId);
		List<AppraiseItem> lists = this.appraiseItemService.find(param);
		initConstant.setAppraiseItems(lists);
	}

	private void initEmployees(Long tenantId, CommonInitConstant initConstant) {
		List<Employee> employees = this.employeeService.findByTenant(tenantId);
		initConstant.setEmployees(employees);
	}

	private void initCustomers(Long tenantId, CommonInitConstant mobileConstant) {
		User user = ActionContextHolder.getContext().getUser();
		List<Customer> customers = this.customerService.getCustomerForMobile(user.getId());
		for (Customer customer : customers) {
			List<NursingProject> projects = this.nursingProjectSrv.findNotDelete("tenant.id",
					tenantId);
			if (projects != null && projects.size() > 0 && projects.get(0).getLevel() != null) {
				customer.setNursingLevel(projects.get(0).getLevel().getName());
			}
			customer.setLeaveStatus(this.customerLeaveService.getLeaveStatus(customer));
		}
		mobileConstant.setCustomers(customers);
	}

	private void initFinishLevel(CommonInitConstant initConstant, Long tenantId, Boolean isDefault) {
		List<ServiceFinishLevel> serviceFinishLevels = this.levelService.findNotDelete("tenant.id",
				tenantId);
		List<ServiceFinishLevel> defaultLevels = this.levelService.findDefaultLevel();
		serviceFinishLevels.addAll(defaultLevels);
		initConstant.setServiceFinishLevel(isDefault ? defaultLevels : serviceFinishLevels);
	}

	private void initBeds(Long tenantId, CommonInitConstant mobileConstant) {
		Map<String, Object> bedParam = Maps.newHashMap();
		bedParam.put("tenant.id", tenantId);
		bedParam.put("delStatus", CommonConstants.DEL_STATUS_NO_0);
		List<Bed> beds = this.bedService.find(bedParam);
		for (Bed bed : beds) {
			bed.setCreateUser(null);
			bed.setLastUpdateUser(null);
			bed.setGroups(null);
			bed.setNursingType(null);
			Customer customer = bed.getCustomer();
			if (customer != null) {
				customer.setBed(null);
			}
		}
		mobileConstant.setBeds(beds);
	}

	private void initDicttypeTenant(Long tenantId, CommonInitConstant mobileConstant) {
		List<DicttypeTenant> dicttypeTenants = this.dicttypeTenantService.findByTenantId(tenantId);
		for (DicttypeTenant dicttypeTenant : dicttypeTenants) {
			Tenant t = dicttypeTenant.getTenant();
			TypegroupTenant group = dicttypeTenant.getTypegroupTenant();
			group.setTenant(null);
			t.setParent(null);
			t.setChildren(null);
			t.setCreateUser(null);
			t.setLastUpdateUser(null);
			dicttypeTenant.setTenant(t);
		}
		mobileConstant.setDicttypeTenants(dicttypeTenants);
	}

	private void initSysConfig(CommonInitConstant mobileConstant) {
		SysConfig config = new SysConfig();
		config.setId(1L);
		mobileConstant.setSysConfig(config);
	}

	private void initDicttype(CommonInitConstant mobileConstant) {
		dslService.setEntityClass(Dicttype.class);
		List<Dicttype> dicttypes = dicttypeService.findAll();
		mobileConstant.setDicttypes(dicttypes);
	}

	private void initTenantPrivileges(Long tenantId, CommonInitConstant initConstant) {
		List<TenantPrivilege> privileges = this.tenantPrivilegeService
				.findInitTenantPrivilkeges(tenantId);
		for (TenantPrivilege tenantPrivilege : privileges) {
			if (tenantPrivilege.getPrivilege() == null) {
				continue;
			}
			tenantPrivilege.getPrivilege().setTenant(null);
		}
		initConstant.setTenantPrivileges(privileges);
	}

	/**
	 * 初始化运营人员的权限
	 *
	 * @author ytche
	 * @param tenantId
	 * @date 2017年7月20日 下午1:53:45
	 */
	private void initOperationPrivileges(Long tenantId, CommonInitConstant initConstant) {
		List<Privilege> privileges = this.privilegeService.findNotDelete();
		initConstant.setPrivileges(privileges);
	}

	private void initConf(CommonInitConstant initContant) {
		List<Conf> confs = this.confService.find("delStatus", CommonConstants.DEL_STATUS_NO_0);
		initContant.setConfs(confs);
	}

	private void initNursingLevel(Long tenantId, CommonInitConstant initConstant) {
		List<NursingLevel> levels = this.nursingLevelService.findNotDelete("tenant.id", tenantId);
		for (NursingLevel nursingLevel : levels) {
			List<NursingLevelServiceItem> services = nursingLevel.getServices();
			for (NursingLevelServiceItem nursingLevelServiceItem : services) {
				nursingLevelServiceItem.setLevel(null);
			}
		}
		initConstant.setNursingLevels(levels);
	}

	private void initNursingLeveItem(Long tenantId, CommonInitConstant initConstant) {
		List<NursingLevelServiceItem> items = this.nursingLevelItemService.findNotDelete(
				"tenant.id", tenantId);
		initConstant.setNursingLevelItems(items);
	}

	private Boolean checkJujia() {
		Integer contextType = ActionContextHolder.getContext().getType();
		return contextType != null && contextType.equals(ICommonConstants.SYSTEM_TYPE_JUJIA_2);
	}

	private void initStaffCustomer(Long tenantId, CommonInitConstant initConstant) {
		User user = ActionContextHolder.getContext().getUser();
		List<Customer> customers = this.customerService.findByUser(user);
		initConstant.setStaffCustomers(customers);
	}
}
